module jinji.common.model;

public import database.sqlbuilder,
database.sqlite,
database.util,
generated,
jinji.common.type,
jinji.config;
public import lmpl4d : nonPacked;
import std.traits : OriginalType;
public import tame.conv : text;

alias Perm = Permissons;

/// 主键
enum PK = sqlkey();
/// 外键
alias FK = foreign;

enum check(string s) = "check(" ~ s ~ ")";
enum check(alias name, T) = text("check(", cast(OriginalType!T)T.min, "<=", name,
		" AND ", name, "<=", text(cast(OriginalType!T)T.max), ")");
/// 默认时间
enum defaultCT = "default(now())";
/// 默认空字符串
enum defEmpty = "default ''";
/// 名称类型
enum nameT = sqltype(text("varchar(", maxNameLength, ")"));
/// 描述类型
enum descT = sqltype(text("varchar(", maxDescLength, ")"));

/// 时间信息
template timeInfo(bool noUpdateTime = false) {
	import jinji.user.model;

	/// 创建者
	@FK!(User.id) Id creator;
	/// 创建时间
	@defaultCT StdTime created_at;
	static if (!noUpdateTime) {
		/// 更新时间
		@check!"updated_at>=created_at"@defaultCT StdTime updated_at;
	}
}

/// 可见性
template Visibility() {
	import jinji.user.model;

	/// 用户id
	@PK @FK!(User.id) Id uid;
	/// 是否可见
	bool visible;
	/// 创建者
	@FK!(User.id) Id creator;
	/// 开始时间
	@defaultCT StdTime start_at;
	/// 结束时间
	@check!"end_at>=start_at"@defaultCT StdTime end_at;
}

/++
判断对象是否对用户可见
id: 对象id
uid: 用户id
+/
bool isVisibleTo(T)(Id id, Id uid) {
	import jinji.db;

	auto q = find!("id=$1 and uid=$2 and start_at<=$3 and end_at>=$3", T.visible)(id, uid, now);
	if (q.empty) {
		return !find!("id=$1 and start_at<=$2 and end_at>=$2", T.visible)(false, id, now);
	}
	return q.get!bool;
}
